package com.px.device.service.impl;

import com.px.common.utils.StringUtils;
import com.px.device.domain.RoutesPointAction;
import com.px.device.domain.RoutesVo;
import com.px.device.domain.RoutesPoint;

import java.util.ArrayList;
import java.util.List;

public class WpmlConversion {

    private static int HETH= 350;
    /***
     *
     * 拼接kml文件
     */
    public String getkml(RoutesVo routesVo){

      StringBuffer sb  = new StringBuffer();
      //文件抬头
      sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
              "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:wpml=\"http://www.dji.com/wpmz/1.0.3\">\n" +
              "<Document>\n");
      //创建人
      sb.append("  <wpml:author>"+routesVo.routesInfo.getCreateBy()+"</wpml:author>\n");
      //创建时间
      sb.append("  <wpml:createTime>"+routesVo.routesInfo.getCreateTime().getTime()+"</wpml:createTime>\n");
      //更新时间
      sb.append("  <wpml:updateTime>"+routesVo.routesInfo.getUpdateTime().getTime()+"</wpml:updateTime>\n");

      sb.append("  <wpml:missionConfig>\n");
      sb.append("    <wpml:flyToWaylineMode>"+routesVo.routesConfig.getFlyToWaylineMode()+"</wpml:flyToWaylineMode>\n");
      sb.append("    <wpml:finishAction>"+routesVo.routesConfig.getFinishAction()+"</wpml:finishAction>\n");
      sb.append("    <wpml:exitOnRCLost>"+routesVo.routesConfig.getExitOnRCLost()+"</wpml:exitOnRCLost>\n");
      sb.append("    <wpml:executeRCLostAction>"+routesVo.routesConfig.getExecuteRCLostAction()+"</wpml:executeRCLostAction>\n");
      sb.append("    <wpml:takeOffSecurityHeight>"+routesVo.routesConfig.getTakeOffSecurityHeight()+"</wpml:takeOffSecurityHeight>\n");
      sb.append("    <wpml:globalTransitionalSpeed>"+routesVo.routesConfig.getGlobalTransitionalSpeed()+"</wpml:globalTransitionalSpeed>\n");

      //飞行器信息
      sb.append("    <wpml:droneInfo>\n");
      sb.append("      <wpml:droneEnumValue>"+routesVo.routesConfig.getDroneEnumValue()+"</wpml:droneEnumValue>\n");
      sb.append("      <wpml:droneSubEnumValue>"+routesVo.routesConfig.getDroneSubEnumValue()+"</wpml:droneSubEnumValue>\n");
      sb.append("    </wpml:droneInfo>\n");

      //负载设置
      sb.append("  <wpml:payloadInfo>\n");
      sb.append("    <wpml:payloadEnumValue>"+routesVo.routesConfig.getPayloadEnumValue()+"</wpml:payloadEnumValue>\n");
      sb.append("    <wpml:payloadSubEnumValue>0</wpml:payloadSubEnumValue>\n");
      sb.append("    <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
      sb.append("  </wpml:payloadInfo>\n");

      //任务信息结束
      sb.append("  </wpml:missionConfig>\n");

      //模板元素
      sb.append("  <Folder>\n");
      //固定为航点模式
      sb.append("    <wpml:templateType>waypoint</wpml:templateType>\n");
      //固定0
      sb.append("    <wpml:templateId>0</wpml:templateId>\n");
      sb.append("    <wpml:autoFlightSpeed>"+routesVo.routesConfig.getAutoFlightSpeed()+"</wpml:autoFlightSpeed>\n");
      //固定坐标系参数信息
      sb.append("    <wpml:waylineCoordinateSysParam>\n");
      sb.append("      <wpml:coordinateMode>WGS84</wpml:coordinateMode>\n");
      sb.append("      <wpml:heightMode>relativeToStartPoint</wpml:heightMode>\n");
      sb.append("    </wpml:waylineCoordinateSysParam>\n");
      sb.append("    <wpml:globalHeight>"+routesVo.routesConfig.getGlobalHeight()+"</wpml:globalHeight>\n");
      sb.append("    <wpml:caliFlightEnable>0</wpml:caliFlightEnable>\n");
      sb.append("    <wpml:gimbalPitchMode>"+routesVo.routesConfig.getGimbalPitchMode()+"</wpml:gimbalPitchMode>\n");
      sb.append("    <wpml:globalWaypointHeadingParam>\n");
      sb.append("      <wpml:waypointHeadingMode>"+routesVo.routesConfig.getWaypointHeadingMode()+"</wpml:waypointHeadingMode>\n");
      sb.append("      <wpml:waypointHeadingAngle>0</wpml:waypointHeadingAngle>\n");
      sb.append("      <wpml:waypointPoiPoint>0.000000,0.000000,0.000000</wpml:waypointPoiPoint>\n");
      sb.append("      <wpml:waypointHeadingPathMode>"+routesVo.routesConfig.getWaypointHeadingPathMode()+"</wpml:waypointHeadingPathMode>\n");
      //不知道什么参数
      sb.append("      <wpml:waypointHeadingPoiIndex>0</wpml:waypointHeadingPoiIndex>\n");
      sb.append("    </wpml:globalWaypointHeadingParam>\n");
      sb.append("    <wpml:globalWaypointTurnMode>"+routesVo.routesConfig.getGlobalWaypointTurnMode()+"</wpml:globalWaypointTurnMode>\n");
      //固定航段轨迹尽量贴合两点连线
      sb.append("    <wpml:globalUseStraightLine>1</wpml:globalUseStraightLine>\n");

      //开始循环点位操作
      routesVo.routesPointList.forEach(routesPoint->{
        sb.append("    <Placemark>\n");
        sb.append("      <Point>\n");
        sb.append("        <coordinates>\n");
//        String[] strings = routesPoint.getCoordinates().split(",");
//        double lat = Double.valueOf(strings[0]);
//        double lon = Double.valueOf(strings[1]);
//        CoordinateUtil.Coordinate coordinate = CoordinateUtil.gcj02ToWgs84(lat, lon);
        sb.append("          "+ routesPoint.getCoordinates()+"\n");
        sb.append("        </coordinates>\n");
        sb.append("      </Point>\n");
        sb.append("      <wpml:index>"+routesPoint.getIndex()+"</wpml:index>\n");
        sb.append("        <wpml:useGlobalHeight>"+routesPoint.getUseGlobalHeight()+"</wpml:useGlobalHeight>\n");
        sb.append("        <wpml:ellipsoidHeight>"+routesPoint.getEllipsoidHeight()+"</wpml:ellipsoidHeight>\n");
        sb.append("        <wpml:height>"+routesPoint.getHeight()+"</wpml:height>\n");
        sb.append("        <wpml:useGlobalSpeed>"+routesPoint.getUseGlobalSpeed()+"</wpml:useGlobalSpeed>\n");
        sb.append("        <wpml:waypointSpeed>"+routesPoint.getWaypointSpeed()+"</wpml:waypointSpeed>\n");

        sb.append("        <wpml:useGlobalHeadingParam>"+routesPoint.getUseGlobalHeadingParam()+"</wpml:useGlobalHeadingParam>\n");
        sb.append("        <wpml:waypointHeadingParam>\n");
        sb.append("          <wpml:waypointHeadingMode>"+routesPoint.getWaypointHeadingMode()+"</wpml:waypointHeadingMode>\n");
        sb.append("          <wpml:waypointHeadingAngle>0</wpml:waypointHeadingAngle>\n");
        sb.append("          <wpml:waypointPoiPoint>0.000000,0.000000,0.000000</wpml:waypointPoiPoint>\n");
        sb.append("          <wpml:waypointHeadingPathMode>"+routesPoint.getWaypointHeadingPathMode()+"</wpml:waypointHeadingPathMode>\n");
        //不知道什么参数
        sb.append("          <wpml:waypointHeadingPoiIndex>0</wpml:waypointHeadingPoiIndex>\n");
        sb.append("        </wpml:waypointHeadingParam>\n");


        //航点过度，不设置
        sb.append("        <wpml:useGlobalTurnParam>1</wpml:useGlobalTurnParam>\n");
        sb.append("        <wpml:gimbalPitchAngle>"+routesPoint.getGimbalPitchAngle()+"</wpml:gimbalPitchAngle>\n");
        int reachPointId = 0 ;
        StringBuffer reachPointSb = new StringBuffer();
        List<Long> multipleTimingList = new ArrayList();
        List<Long> multipleDistanceList = new ArrayList();

        for (int i = 0; i < routesPoint.routesPointActionList.size(); i++) {
          String actionActuatorFunc = routesPoint.routesPointActionList.get(i).getActionActuatorFunc();
          Long value = routesPoint.routesPointActionList.get(i).getValue();

          switch (actionActuatorFunc)
          {
            case "takePhoto":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
              reachPointSb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "startRecord":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>startRecord</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
              reachPointSb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "stopRecord":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>stopRecord</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "zoom":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>zoom</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:focalLength>"+value+"</wpml:focalLength>\n");
              reachPointSb.append("              <wpml:isUseFocalFactor>0</wpml:isUseFocalFactor>\n");
              reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "rotateYaw":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>rotateYaw</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:aircraftHeading>"+value+"</wpml:aircraftHeading>\n");
              reachPointSb.append("              <wpml:aircraftPathMode>counterClockwise</wpml:aircraftPathMode>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "hover":
              reachPointSb.append("          <wpml:action>\n");
              reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
              reachPointSb.append("            <wpml:actionActuatorFunc>hover</wpml:actionActuatorFunc>\n");
              reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("              <wpml:hoverTime>"+value+"</wpml:hoverTime>\n");
              reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
              reachPointSb.append("          </wpml:action>\n");
              reachPointId++;
              break;
            case "multipleTiming":
              multipleTimingList.add(value);
              break;
            case "multipleDistance":
              multipleDistanceList.add(value);
              break;
            case "multipleStop":
              break;
            default:
              break;
          }

        }
        reachPointId = 0;
        int actionGroupId = 0;
        if(StringUtils.isNotEmpty(reachPointSb)){
          sb.append("        <wpml:actionGroup>\n");
          sb.append("          <wpml:actionGroupId>"+actionGroupId+"</wpml:actionGroupId>\n");
          sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
          sb.append("          <wpml:actionGroupEndIndex>"+routesPoint.getIndex()+"</wpml:actionGroupEndIndex>\n");
          sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
          sb.append("          <wpml:actionTrigger>\n");
          sb.append("            <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType>\n");
          sb.append("          </wpml:actionTrigger>\n");
          sb.append(reachPointSb);
          sb.append("        </wpml:actionGroup>\n");
          actionGroupId++;
        }

        if(multipleTimingList.size() > 0){
          for (Long v : multipleTimingList){
            sb.append("        <wpml:actionGroup>\n");
            sb.append("          <wpml:actionGroupId>"+ actionGroupId +"</wpml:actionGroupId>\n");
            sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
            //这里去查最后一次结束动作
            int actionGroupEndIndex = getActionGroupEndIndex(routesVo.routesPointList,routesPoint.getIndex().intValue());
            sb.append("          <wpml:actionGroupEndIndex>"+actionGroupEndIndex+"</wpml:actionGroupEndIndex>\n");
            sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
            sb.append("          <wpml:actionTrigger>\n");
            sb.append("            <wpml:actionTriggerType>multipleTiming</wpml:actionTriggerType>\n");
            sb.append("            <wpml:actionTriggerParam>"+v+"</wpml:actionTriggerParam>\n");
            sb.append("          </wpml:actionTrigger>\n");
            sb.append("          <wpml:action>\n");
            sb.append("            <wpml:actionId>0</wpml:actionId>\n");
            sb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
            sb.append("            <wpml:actionActuatorFuncParam>\n");
            sb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            sb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
            sb.append("            </wpml:actionActuatorFuncParam>\n");
            sb.append("          </wpml:action>\n");
            sb.append("        </wpml:actionGroup>\n");
            actionGroupId++;
          }
        }

        if(multipleDistanceList.size() > 0){
          for (Long v : multipleDistanceList){
            sb.append("        <wpml:actionGroup>\n");
            sb.append("          <wpml:actionGroupId>"+ actionGroupId +"</wpml:actionGroupId>\n");
            sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
            //这里去查最后一次结束动作
            int actionGroupEndIndex = getActionGroupEndIndex(routesVo.routesPointList,routesPoint.getIndex().intValue());
            sb.append("          <wpml:actionGroupEndIndex>"+actionGroupEndIndex+"</wpml:actionGroupEndIndex>\n");
            sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
            sb.append("          <wpml:actionTrigger>\n");
            sb.append("            <wpml:actionTriggerType>multipleDistance</wpml:actionTriggerType>\n");
            sb.append("            <wpml:actionTriggerParam>"+v+"</wpml:actionTriggerParam>\n");
            sb.append("          </wpml:actionTrigger>\n");
            sb.append("          <wpml:action>\n");
            sb.append("            <wpml:actionId>0</wpml:actionId>\n");
            sb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
            sb.append("            <wpml:actionActuatorFuncParam>\n");
            sb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            sb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
            sb.append("            </wpml:actionActuatorFuncParam>\n");
            sb.append("          </wpml:action>\n");
            sb.append("        </wpml:actionGroup>\n");
            actionGroupId++;
          }
        }
        sb.append("    </Placemark>\n");

      });
      sb.append("      <wpml:payloadParam>\n");
      sb.append("        <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
      sb.append("        <wpml:focusMode>firstPoint</wpml:focusMode>\n");
      sb.append("        <wpml:dewarpingEnable>1</wpml:dewarpingEnable>\n");
      sb.append("        <wpml:meteringMode>average</wpml:meteringMode>\n");
      sb.append("        <wpml:returnMode>singleReturnFirst</wpml:returnMode>\n");
      sb.append("        <wpml:samplingRate>240000</wpml:samplingRate>\n");
      sb.append("        <wpml:scanningMode>repetitive</wpml:scanningMode>\n");
      sb.append("        <wpml:imageFormat>wide,zoom</wpml:imageFormat>\n");
      sb.append("      </wpml:payloadParam>\n");
      sb.append("  </Folder>\n");
      //结束
      sb.append("\n</Document>\n" +
              "</kml>");
      return sb.toString();
    }

  //获取结束间隔的点位，没有就传最后一位
  public int getActionGroupEndIndex(List<RoutesPoint> routesPoint, int pointIndex){
    for (int i = pointIndex; i < routesPoint.size(); i++) {
      List<RoutesPointAction> RoutesPointAction = routesPoint.get(i).routesPointActionList;
      for (RoutesPointAction action : RoutesPointAction){
        if("multipleStop".equals(action.getActionActuatorFunc())){
          return i;
        }
      }
    }
      return routesPoint.size()-1;
    }

  /***
   *
   * 拼接wpml 文件
   */
  public String getwpml(RoutesVo routesVo){
    StringBuffer sb = new StringBuffer();

    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:wpml=\"http://www.dji.com/wpmz/1.0.3\">\n" +
            "  <Document>");
    sb.append("  <wpml:missionConfig>\n");
    sb.append("    <wpml:flyToWaylineMode>"+routesVo.routesConfig.getFlyToWaylineMode()+"</wpml:flyToWaylineMode>\n");
    sb.append("    <wpml:finishAction>"+routesVo.routesConfig.getFinishAction()+"</wpml:finishAction>\n");
    sb.append("    <wpml:exitOnRCLost>"+routesVo.routesConfig.getExitOnRCLost()+"</wpml:exitOnRCLost>n\n");
    sb.append("    <wpml:executeRCLostAction>"+routesVo.routesConfig.getExecuteRCLostAction()+"</wpml:executeRCLostAction>\n");
    sb.append("    <wpml:takeOffSecurityHeight>"+routesVo.routesConfig.getTakeOffSecurityHeight()+"</wpml:takeOffSecurityHeight>\n");
    sb.append("    <wpml:globalTransitionalSpeed>"+routesVo.routesConfig.getGlobalTransitionalSpeed()+"</wpml:globalTransitionalSpeed>\n");

    //飞行器信息
    sb.append("    <wpml:droneInfo>\n");
    sb.append("      <wpml:droneEnumValue>"+routesVo.routesConfig.getDroneEnumValue()+"</wpml:droneEnumValue>\n");
    sb.append("      <wpml:droneSubEnumValue>"+routesVo.routesConfig.getDroneSubEnumValue()+"</wpml:droneSubEnumValue>\n");
    sb.append("    </wpml:droneInfo>\n");

    //负载设置
    sb.append("    <wpml:payloadInfo>\n");
    sb.append("      <wpml:payloadEnumValue>"+routesVo.routesConfig.getPayloadEnumValue()+"</wpml:payloadEnumValue>\n");
    sb.append("      <wpml:payloadSubEnumValue>0</wpml:payloadSubEnumValue>\n");
    sb.append("      <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
    sb.append("    </wpml:payloadInfo>\n");

    //任务信息结束
    sb.append("  </wpml:missionConfig>\n");

    sb.append("    <Folder>\n");
    sb.append("      <wpml:templateId>0</wpml:templateId>\n");
    sb.append("      <wpml:executeHeightMode>relativeToStartPoint</wpml:executeHeightMode>\n");
    sb.append("      <wpml:waylineId>0</wpml:waylineId>\n");
    sb.append("      <wpml:autoFlightSpeed>"+routesVo.routesConfig.getAutoFlightSpeed()+"</wpml:autoFlightSpeed>\n");
    //开始循环点位操作
    routesVo.routesPointList.forEach(routesPoint->{

      sb.append("      <Placemark>\n");
      sb.append("        <Point>\n");
      sb.append("          <coordinates>\n");
//      String[] strings = routesPoint.getCoordinates().split(",");
//      double lat = Double.valueOf(strings[0]);
//      double lon = Double.valueOf(strings[1]);
//      CoordinateUtil.Coordinate coordinate = CoordinateUtil.gcj02ToWgs84(lat, lon);
//      sb.append("          "+ coordinate.getLng() + "," + coordinate.getLat()+"\n");
      sb.append("          "+ routesPoint.getCoordinates()+"\n");
      sb.append("          </coordinates>\n");
      sb.append("        </Point>\n");
      sb.append("        <wpml:index>"+routesPoint.getIndex()+"</wpml:index>\n");
      sb.append("        <wpml:executeHeight>"+routesPoint.getExecuteHeight()+"</wpml:executeHeight>\n");
      sb.append("        <wpml:waypointSpeed>"+routesPoint.getWaypointSpeed()+"</wpml:waypointSpeed>\n");

      sb.append("        <wpml:waypointHeadingParam>\n");
      sb.append("          <wpml:waypointHeadingMode>"+routesPoint.getWaypointHeadingMode()+"</wpml:waypointHeadingMode>\n");
      sb.append("          <wpml:waypointHeadingAngle>0</wpml:waypointHeadingAngle>\n");
      sb.append("          <wpml:waypointPoiPoint>0.000000,0.000000,0.000000</wpml:waypointPoiPoint>\n");
      sb.append("          <wpml:waypointHeadingPathMode>"+routesPoint.getWaypointHeadingPathMode()+"</wpml:waypointHeadingPathMode>\n");
      //不知道什么参数
      sb.append("          <wpml:waypointHeadingPoiIndex>0</wpml:waypointHeadingPoiIndex>\n");
      sb.append("        </wpml:waypointHeadingParam>\n");

      sb.append("        <wpml:waypointTurnParam>\n");
      sb.append("          <wpml:waypointTurnMode>toPointAndStopWithDiscontinuityCurvature</wpml:waypointTurnMode>\n");
      sb.append("          <wpml:waypointTurnDampingDist>0.2</wpml:waypointTurnDampingDist>\n");
      sb.append("        </wpml:waypointTurnParam>\n");

      sb.append("        <wpml:useStraightLine>1</wpml:useStraightLine>\n");



      int reachPointId = 0 ;
      StringBuffer reachPointSb = new StringBuffer();
      List<Long> multipleTimingList = new ArrayList();
      List<Long> multipleDistanceList = new ArrayList();

      sb.append("        <wpml:actionGroup>\n");
      sb.append("          <wpml:actionGroupId>"+0+"</wpml:actionGroupId>\n");
      sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
      sb.append("          <wpml:actionGroupEndIndex>"+routesPoint.getIndex()+"</wpml:actionGroupEndIndex>\n");
      sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
      sb.append("          <wpml:actionTrigger>\n");
      sb.append("            <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType>\n");
      sb.append("          </wpml:actionTrigger>\n");
      sb.append("          <wpml:action>\n");
      sb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
      sb.append("            <wpml:actionActuatorFunc>gimbalRotate</wpml:actionActuatorFunc>\n");
      sb.append("            <wpml:actionActuatorFuncParam>\n");
      sb.append("              <wpml:gimbalRotateMode>absoluteAngle</wpml:gimbalRotateMode>\n");
      sb.append("              <wpml:gimbalPitchRotateEnable>1</wpml:gimbalPitchRotateEnable>\n");
      sb.append("              <wpml:gimbalPitchRotateAngle>"+routesPoint.getGimbalPitchAngle()+"</wpml:gimbalPitchRotateAngle>\n");
      sb.append("              <wpml:gimbalRollRotateEnable>0</wpml:gimbalRollRotateEnable>\n");
      sb.append("              <wpml:gimbalRollRotateAngle>0.0</wpml:gimbalRollRotateAngle>\n");
      sb.append("              <wpml:gimbalYawRotateEnable>0</wpml:gimbalYawRotateEnable>\n");
      sb.append("              <wpml:gimbalYawRotateAngle>0.0</wpml:gimbalYawRotateAngle>\n");
      sb.append("              <wpml:gimbalRotateTimeEnable>0</wpml:gimbalRotateTimeEnable>\n");
      sb.append("              <wpml:gimbalRotateTime>0.0</wpml:gimbalRotateTime>\n");
      sb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
      sb.append("            </wpml:actionActuatorFuncParam>\n");
      sb.append("          </wpml:action>\n");
      sb.append("        </wpml:actionGroup>\n");

      for (int i = 0; i < routesPoint.routesPointActionList.size(); i++) {
        String actionActuatorFunc = routesPoint.routesPointActionList.get(i).getActionActuatorFunc();
        Long value = routesPoint.routesPointActionList.get(i).getValue();

        switch (actionActuatorFunc)
        {
          case "takePhoto":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            reachPointSb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "startRecord":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>startRecord</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            reachPointSb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "stopRecord":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>stopRecord</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "zoom":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>zoom</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:focalLength>"+value+"</wpml:focalLength>\n");
            reachPointSb.append("              <wpml:isUseFocalFactor>0</wpml:isUseFocalFactor>\n");
            reachPointSb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "rotateYaw":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>rotateYaw</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:aircraftHeading>"+value+"</wpml:aircraftHeading>\n");
            reachPointSb.append("              <wpml:aircraftPathMode>counterClockwise</wpml:aircraftPathMode>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "hover":
            reachPointSb.append("          <wpml:action>\n");
            reachPointSb.append("            <wpml:actionId>"+reachPointId+"</wpml:actionId>\n");
            reachPointSb.append("            <wpml:actionActuatorFunc>hover</wpml:actionActuatorFunc>\n");
            reachPointSb.append("            <wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("              <wpml:hoverTime>"+value+"</wpml:hoverTime>\n");
            reachPointSb.append("            </wpml:actionActuatorFuncParam>\n");
            reachPointSb.append("          </wpml:action>\n");
            reachPointId++;
            break;
          case "multipleTiming":
            multipleTimingList.add(value);
            break;
          case "multipleDistance":
            multipleDistanceList.add(value);
            break;
          case "multipleStop":
            break;
          default:
            break;
        }

      }
      reachPointId = 0;
      int actionGroupId = 1;
      if(StringUtils.isNotEmpty(reachPointSb)){
        sb.append("        <wpml:actionGroup>\n");
        sb.append("          <wpml:actionGroupId>"+actionGroupId+"</wpml:actionGroupId>\n");
        sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
        sb.append("          <wpml:actionGroupEndIndex>"+routesPoint.getIndex()+"</wpml:actionGroupEndIndex>\n");
        sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
        sb.append("          <wpml:actionTrigger>\n");
        sb.append("            <wpml:actionTriggerType>reachPoint</wpml:actionTriggerType>\n");
        sb.append("          </wpml:actionTrigger>\n");
        sb.append(reachPointSb);
        sb.append("        </wpml:actionGroup>\n");
        actionGroupId++;
      }

      if(multipleTimingList.size() > 0){
        for (Long v : multipleTimingList){
          sb.append("        <wpml:actionGroup>\n");
          sb.append("          <wpml:actionGroupId>"+ actionGroupId +"</wpml:actionGroupId>\n");
          sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
          //这里去查最后一次结束动作
          int actionGroupEndIndex = getActionGroupEndIndex(routesVo.routesPointList,routesPoint.getIndex().intValue());
          sb.append("          <wpml:actionGroupEndIndex>"+actionGroupEndIndex+"</wpml:actionGroupEndIndex>\n");
          sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
          sb.append("          <wpml:actionTrigger>\n");
          sb.append("            <wpml:actionTriggerType>multipleTiming</wpml:actionTriggerType>\n");
          sb.append("            <wpml:actionTriggerParam>"+v+"</wpml:actionTriggerParam>\n");
          sb.append("          </wpml:actionTrigger>\n");
          sb.append("          <wpml:action>\n");
          sb.append("            <wpml:actionId>0</wpml:actionId>\n");
          sb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
          sb.append("            <wpml:actionActuatorFuncParam>\n");
          sb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
          sb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
          sb.append("            </wpml:actionActuatorFuncParam>\n");
          sb.append("          </wpml:action>\n");
          sb.append("        </wpml:actionGroup>\n");
          actionGroupId++;
        }
      }

      if(multipleDistanceList.size() > 0){
        for (Long v : multipleDistanceList){
          sb.append("        <wpml:actionGroup>\n");
          sb.append("          <wpml:actionGroupId>"+ actionGroupId +"</wpml:actionGroupId>\n");
          sb.append("          <wpml:actionGroupStartIndex>"+routesPoint.getIndex()+"</wpml:actionGroupStartIndex>\n");
          //这里去查最后一次结束动作
          int actionGroupEndIndex = getActionGroupEndIndex(routesVo.routesPointList,routesPoint.getIndex().intValue());
          sb.append("          <wpml:actionGroupEndIndex>"+actionGroupEndIndex+"</wpml:actionGroupEndIndex>\n");
          sb.append("          <wpml:actionGroupMode>sequence</wpml:actionGroupMode>\n");
          sb.append("          <wpml:actionTrigger>\n");
          sb.append("            <wpml:actionTriggerType>multipleDistance</wpml:actionTriggerType>\n");
          sb.append("            <wpml:actionTriggerParam>"+v+"</wpml:actionTriggerParam>\n");
          sb.append("          </wpml:actionTrigger>\n");
          sb.append("          <wpml:action>\n");
          sb.append("            <wpml:actionId>0</wpml:actionId>\n");
          sb.append("            <wpml:actionActuatorFunc>takePhoto</wpml:actionActuatorFunc>\n");
          sb.append("            <wpml:actionActuatorFuncParam>\n");
          sb.append("              <wpml:payloadPositionIndex>0</wpml:payloadPositionIndex>\n");
          sb.append("              <wpml:useGlobalPayloadLensIndex>1</wpml:useGlobalPayloadLensIndex>\n");
          sb.append("            </wpml:actionActuatorFuncParam>\n");
          sb.append("          </wpml:action>\n");
          sb.append("        </wpml:actionGroup>\n");
          actionGroupId++;
        }
      }
      sb.append("    </Placemark>\n");

    });

    sb.append("    </Folder>\n");
    sb.append("  </Document>\n" +
            "</kml>");
    return sb.toString();
  }

}
